package com.liantong.service.cms;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.liantong.common.dao.PreviewDao;
import com.liantong.common.mapper.AppMapper;
import com.liantong.common.mapper.CommentMapper;
import com.liantong.common.mapper.PreviewMapper;
import com.liantong.common.po.App;
import com.liantong.common.po.AppExample;
import com.liantong.common.po.Preview;
import com.liantong.common.po.PreviewExample;
import com.liantong.common.vo.InsertAppInfo;
import com.liantong.service.util.AppUuidGenerator;
import com.liantong.service.util.FileUtil;
import com.liantong.service.util.ParseApkUtil;
import com.liantong.util.MD5Util;
import com.liantong.util.StringUtil;

@Service("appService")
public class AppService  {
	
	@Resource(name="appMapper")
	private AppMapper appMapper;

	@Resource(name="commentMapper")
	private CommentMapper commentMapper;

	@Resource(name="previewMapper")
	private PreviewMapper previewMapper;
	
	@Resource(name="previewDao")
	private PreviewDao previewDao;
	
	@Transactional
	public void insertApp(InsertAppInfo insertAppInfo) throws Exception {

		//App app = setApkInfo(insertAppInfo.getApp(), insertAppInfo.getApk());

		//checkAppExistLastVersion(app.getVersionCode(), app.getPackageName(), insertAppInfo.getContextPath());
		App app = insertAppInfo.getApp();
		app.setId(AppUuidGenerator.generate());

		copyAppFile(app, insertAppInfo);

		appMapper.insert(app);
	}
	
	public List<App> getAll(){
		AppExample example = new AppExample();
		example.createCriteria().andIdIsNotNull();
		List<App> result = appMapper.selectByExample(example);
		
		for (App r : result) {
			r.setAvatar(FileUtil.getRealPath(r.getAvatar()));
			r.setRespath(FileUtil.getRealPath(r.getRespath()));
		}
		return result;
	}
	
	private App setApkInfo(App app, File apk) {

		Map<String, String> apkInfo = ParseApkUtil.parse(apk);
		String versionName = apkInfo.get(ParseApkUtil.VERSIONNAME);
		String versionCode = apkInfo.get(ParseApkUtil.VERSIONCODE);
		int versionCodeV = 0;
		if (!StringUtil.isBlank(versionCode)) {
			versionCodeV = Integer.parseInt(versionCode);
		}
		String packageName = apkInfo.get(ParseApkUtil.PACKAGENAME);
	//	app.setVersionCode(versionCodeV);
		app.setVersionName(versionName);
		app.setMd5Code(MD5Util.getMD5(apk));
		app.setPackageName(packageName);
		app.setSize((int) apk.length());

		return app;
	}
	
	private void checkAppExistLastVersion(int versionCode, String packageName, String contextPath) throws Exception {
		AppExample example = new AppExample();
		example.createCriteria().andPackageNameEqualTo(packageName);
		List<App> existApps = appMapper.selectByExample(example);

		if (null != existApps && existApps.size()>0) {
			App existApp = existApps.get(0);
			//int existVersionCode = existApp.getVersionCode();
/*
			if (existVersionCode >= versionCode) {

				//log.info("EXIST_THE_LAST_VERSION");
				throw new Exception("EXIST_THE_LAST_VERSION");
			} else {
				String appId = existApp.getId();
				delete(appId, contextPath);
			}*/
		}
	}

	public void delete(String appId, String contextPath) {

		// TODO delete table : rayhov_recommend / comment / preview / index

		App existApp = appMapper.selectByPrimaryKey(appId);

		if (null != existApp) {

			appMapper.deleteByPrimaryKey(appId);
			
			// delete APP file
			deleteAppFile(existApp, contextPath);
			
			PreviewExample example = new PreviewExample();
			example.createCriteria().andAppIdEqualTo(appId);
			previewMapper.deleteByExample(example);
		}
	}
	
	private void deleteAppFile(App app, String contextPath) {
		FileUtil.delete(contextPath + app.getAvatar());
		FileUtil.delete(contextPath + app.getRespath());

		PreviewExample example = new PreviewExample();
		example.createCriteria().andAppIdEqualTo(app.getId());
		List<Preview> previews = previewMapper.selectByExample(example);
		for(Preview p : previews){
			String path = p.getResPath();
			FileUtil.delete(contextPath + path);
		}
	}
	
	private void copyAppFile(App app, InsertAppInfo insertAppInfo) throws Exception {
		List<String> previewsPath = new ArrayList<String>();

		String id = String.valueOf(app.getId());

		String contextPath = insertAppInfo.getContextPath();

//		String apkFilePath = copyAppFile(id, insertAppInfo.getApkPath(), contextPath, insertAppInfo.getApkName(),
//				insertAppInfo.getApk());
//		app.setRespath(apkFilePath);

		String avatarFilePath = copyAppFile(id, insertAppInfo.getAvatarPath(), contextPath, insertAppInfo.getAvatarName(),
				insertAppInfo.getAvatar());
		app.setAvatar(avatarFilePath);

		previewsPath = copyPreviewFile(id, insertAppInfo.getPreviews(), insertAppInfo.getPreviewNames(), contextPath,
				insertAppInfo.getPreviewPath());


		addPreviews(app.getId(), previewsPath);
	}
	
	private String copyAppFile(String appId, String toParentFilePath, String toContentPath, String fromFileName, File fromFile) throws Exception {

		String toFileName = "";
		try {
			toFileName = toParentFilePath + FileUtil.getDestinationFilePath(appId, MD5Util.getMD5(fromFile), fromFileName);
			FileUtils.copyFile(fromFile, new File(toContentPath + toFileName));

		} catch (IOException e) {
			throw new Exception(e);
		}
		return toFileName;
	}
	
	private List<String> copyPreviewFile(String id, File[] previews, String[] previewsName, String contextPath, String previewPath) throws Exception {

		List<String> result = new ArrayList<String>();

		for (int i = 0; i < previews.length; i++) {
			File previewFile = previews[i];
			String previewName = previewsName[i];

			String previewFilePath = copyAppFile(id, previewPath, contextPath, previewName, previewFile);
			result.add(previewFilePath);
		}

		return result;
	}
	
	private void addPreviews(String appId, List<String> preview) {
		List<Preview> previewList = new ArrayList<Preview>();

		for (String respath : preview) {
			Preview pv = new Preview();

			pv.setId(AppUuidGenerator.generate());
			pv.setAppId(appId);
			pv.setResPath(respath);

			previewList.add(pv);			
		}
		previewDao.batchInsert(previewList);

		
	}

}
